package com.wxmblog.photo.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wxmblog.base.common.utils.PageResult;
import com.wxmblog.base.common.utils.TokenUtils;
import com.wxmblog.base.file.service.MsfFileService;
import com.wxmblog.photo.common.rest.request.product.admin.EditProductRequest;
import com.wxmblog.photo.common.rest.request.product.admin.ProductAdminRequest;
import com.wxmblog.photo.common.rest.request.product.front.ProductIndexRequest;
import com.wxmblog.photo.common.rest.response.product.admin.ProductResponse;
import com.wxmblog.photo.common.rest.response.product.front.ProductIndexResponse;
import com.wxmblog.photo.dao.ProductDao;
import com.wxmblog.photo.entity.ProductCollectEntity;
import com.wxmblog.photo.entity.ProductEntity;
import com.wxmblog.photo.entity.ViewRecordEntity;
import com.wxmblog.photo.service.ProductCollectService;
import com.wxmblog.photo.service.ViewRecordService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wxmblog.photo.service.ProductService;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;


@Service("productService")
public class ProductServiceImpl extends ServiceImpl<ProductDao, ProductEntity> implements ProductService {

    @Autowired
    MsfFileService msfFileService;

    @Autowired
    ProductCollectService productCollectService;

    @Autowired
    ViewRecordService viewRecordService;

    @Transactional
    @Override
    public void editProduct(EditProductRequest request) {

        ProductEntity productEntity = new ProductEntity();
        BeanUtils.copyProperties(request, productEntity);
        if (request.getId() == null) {
            this.baseMapper.insert(productEntity);
        } else {
            Wrapper<ProductEntity> wrapper = new QueryWrapper<ProductEntity>().lambda()
                    .eq(ProductEntity::getId, request.getId());
            this.baseMapper.update(productEntity, wrapper);
        }

    }

    @Override
    public Long countByCategoryId(Integer categoryId) {
        Wrapper<ProductEntity> productEntityWrapper = new QueryWrapper<ProductEntity>().lambda()
                .eq(ProductEntity::getCategoryId, categoryId);
        return this.baseMapper.selectCount(productEntityWrapper);
    }

    @Override
    public PageResult<ProductResponse> page(ProductAdminRequest request, Integer pageIndex, Integer pageSize) {

        if (StringUtils.isNotBlank(request.getTitle())) {
            request.setTitle("%" + request.getTitle() + "%");
        }

        Page<ProductResponse> page = PageHelper.startPage(pageIndex, pageSize);
        this.baseMapper.getPage(request);
        PageResult<ProductResponse> result = new PageResult<>(page);
        return result;
    }

    @Override
    public ProductResponse info(Integer id) {
        return this.baseMapper.info(id);
    }

    @Transactional
    @Override
    public void delete(Integer id) {

        ProductEntity productEntity = this.getById(id);
        if (productEntity != null) {
            this.removeById(id);
            if (StringUtils.isNotBlank(productEntity.getFile())) {
                msfFileService.deleteFileByUrl(productEntity.getFile());
            }
        }
    }

    @Override
    public PageResult<ProductIndexResponse> frontPage(ProductIndexRequest request, Integer pageIndex, Integer pageSize) {

        if (StringUtils.isNotBlank(request.getKeyWord())) {
            request.setKeyWord("%" + request.getKeyWord() + "%");
        }

        request.setUserId(TokenUtils.getOwnerId());

        Page<ProductIndexResponse> page = PageHelper.startPage(pageIndex, pageSize);
        this.baseMapper.frontPage(request);
        PageResult<ProductIndexResponse> result = new PageResult<>(page);

        result.getRows().forEach(model -> {
            model.setFileName(msfFileService.getFileNameByUrl(model.getFile()));
        });
        return result;
    }

    @Override
    public List<ProductIndexResponse> recommend(ProductIndexRequest request) {


        if (StringUtils.isNotBlank(request.getKeyWord())) {
            request.setKeyWord("%" + request.getKeyWord() + "%");
        }

        if (request.getProductId() != null) {
            ProductEntity productEntity = this.getBaseMapper().selectById(request.getProductId());
            if (productEntity != null && CollectionUtil.isNotEmpty(productEntity.getLabel())) {
                List<String> labels = new ArrayList<>();
                productEntity.getLabel().forEach(model -> {
                    labels.add("%" + model + "%");
                });
                request.setLabelList(labels);
            }
        }

        request.setUserId(TokenUtils.getOwnerId());

        List<ProductIndexResponse> result = this.baseMapper.recommend(request);

        result.forEach(model -> {
            model.setFileName(msfFileService.getFileNameByUrl(model.getFile()));
        });
        return result;
    }

    @Transactional
    @Override
    public void collect(Integer id, Boolean result) {
        Wrapper<ProductCollectEntity> wrapper = new QueryWrapper<ProductCollectEntity>().lambda()
                .eq(ProductCollectEntity::getProductId, id)
                .eq(ProductCollectEntity::getUserId, TokenUtils.getOwnerId());
        //取消收藏
        if (Boolean.FALSE.equals(result)) {

            productCollectService.getBaseMapper().delete(wrapper);
        } else if (Boolean.TRUE.equals(result)) {
            //收藏
            Long count = productCollectService.getBaseMapper().selectCount(wrapper);
            if (count == 0) {
                ProductCollectEntity productCollectEntity = new ProductCollectEntity();
                productCollectEntity.setUserId(TokenUtils.getOwnerId());
                productCollectEntity.setProductId(id);
                productCollectService.save(productCollectEntity);
            }
        }

    }

    @Transactional
    @Override
    public void view(Integer id, Integer userId) {

        Wrapper<ViewRecordEntity> recordEntityWrapper = new QueryWrapper<ViewRecordEntity>().lambda()
                .eq(ViewRecordEntity::getProductId, id)
                .eq(ViewRecordEntity::getUserId, userId);
        this.viewRecordService.remove(recordEntityWrapper);

        ViewRecordEntity viewRecordEntity = new ViewRecordEntity();
        viewRecordEntity.setUserId(userId);
        viewRecordEntity.setProductId(id);
        this.viewRecordService.save(viewRecordEntity);
    }

    @Override
    public PageResult<ProductIndexResponse> downloadRecord(Integer pageIndex, Integer pageSize) {

        Page<ProductIndexResponse> page = PageHelper.startPage(pageIndex, pageSize);
        this.baseMapper.downloadRecord(TokenUtils.getOwnerId());
        PageResult<ProductIndexResponse> result = new PageResult<>(page);
        result.getRows().forEach(model -> {
            model.setFileName(msfFileService.getFileNameByUrl(model.getFile()));
        });
        return result;
    }

    @Override
    public PageResult<ProductIndexResponse> collectRecord(Integer pageIndex, Integer pageSize) {
        Page<ProductIndexResponse> page = PageHelper.startPage(pageIndex, pageSize);
        this.baseMapper.collectRecord(TokenUtils.getOwnerId());
        PageResult<ProductIndexResponse> result = new PageResult<>(page);
        result.getRows().forEach(model -> {
            model.setFileName(msfFileService.getFileNameByUrl(model.getFile()));
        });
        return result;
    }

    @Override
    public PageResult<ProductIndexResponse> viewRecord(Integer pageIndex, Integer pageSize) {
        Page<ProductIndexResponse> page = PageHelper.startPage(pageIndex, pageSize);
        this.baseMapper.viewRecord(TokenUtils.getOwnerId());
        PageResult<ProductIndexResponse> result = new PageResult<>(page);
        result.getRows().forEach(model -> {
            model.setFileName(msfFileService.getFileNameByUrl(model.getFile()));
        });
        return result;
    }
}
